<template>
  <div class="search-box">
    <EcoForm :items-props="itemsProps" v-model="model" ref="formRef" :enum-map-props>
      <template #default="{ getComponentWidth }">
        <Grid
          ref="gridRef"
          :collapsed="getProps.useCollapsed ? getProps.collapsed : false"
          :cols="getProps.searchCols"
          :gap="gap"
          :collapsed-rows="getProps.collapsedRows"
        >
          <GridItem v-for="(item, index) in searchForm" :key="item.prop" v-bind="getResponsive(item)" :index="index">
            <el-form-item :label="item.label">
              <EcoItem :style="getComponentWidth(item)" :item="item" v-model="model" />
            </el-form-item>
          </GridItem>
          <GridItem suffix>
            <div class="search-operation">
              <slot name="action" :model="model" :show-collapse="showCollapse" :toggle-collapsed="toggleCollapsed">
                <el-button type="primary" icon="Search" @click="search">搜索</el-button>
                <el-button icon="Delete" @click="reset">重置</el-button>
                <el-button v-if="showCollapse" type="primary" link @click="toggleCollapsed()">
                  {{ getProps.collapsed ? '展开' : '合并' }}
                  <el-icon class="el-icon--right">
                    <component :is="getProps.collapsed ? 'ArrowDown' : 'ArrowUp'"></component>
                  </el-icon>
                </el-button>
              </slot>
            </div>
          </GridItem>
        </Grid>
      </template>
    </EcoForm>
  </div>
</template>

<script lang="ts" setup name="EcoSearch">
import { GridItemProps } from '@/components/Grid/components/GridItem.vue'
import Grid from '@/components/Grid/index.vue'
import EcoForm from '@/components/EcoForm/index.vue'
export interface EcoSearchProps {
  formProps?: EcoForm.Form
  itemsProps?: EcoSearchColumnsProps[]
  useCollapsed?: boolean // 是否使用折叠功能
  collapsed?: boolean // 是否默认折叠搜索项
  searchCols?: number | Record<BreakPoint, number>
  collapsedRows?: number // 可见的行数
  gap?: [number, number] | number // 行和列间距
  showSearch?: boolean // 是否展示搜索按钮
  showReset?: boolean // 是否展示重置按钮
  searchLoading?: boolean // 搜索按钮的 loading
  resetLoading?: boolean // 搜索按钮的 loading
  removeNoValue?: boolean // 是否去除空值项
  enumMapProps?: Map<string, Record<string, any>[]>
  search?: (params: any) => void // 搜索方法
  reset?: (params: any) => void // 重置方法
}

export type EcoSearchColumnsProps = EcoForm.Item & {
  grid?: Partial<GridItemProps> // GridItem 的 props
}
const props = withDefaults(defineProps<EcoSearchProps>(), {
  itemsProps: () => [],
  position: 'right',
  useCollapsed: true,
  searchCols: () => ({ xs: 1, sm: 2, md: 2, lg: 3, xl: 4 }),
  collapsed: true,
  collapsedRows: 1,
  gap: () => [20, 0],
  showSearch: true,
  showReset: true,
  searchLoading: false,
  resetLoading: false,
  removeNoValue: true
})

const model = defineModel<Record<string, any>>({ default: {} })
const mergeProps = ref<EcoSearchProps>({})
const formRef = shallowRef<InstanceType<typeof EcoForm>>()
const getProps = computed(() => {
  const propsObj = { ...props }
  Object.assign(propsObj, unref(mergeProps))
  return propsObj
})
// 获取响应式设置
const getResponsive = (item: EcoSearchColumnsProps) => {
  return {
    span: item.grid?.span,
    offset: item.grid?.offset ?? 0,
    xs: item.grid?.xs,
    sm: item.grid?.sm,
    md: item.grid?.md,
    lg: item.grid?.lg,
    xl: item.grid?.xl
  }
}
// 设置 EcoForm 组件的 props
const setProps = (props: EcoSearchProps = {}) => {
  mergeProps.value = Object.assign(unref(mergeProps), props)
}
const gridRef = shallowRef<InstanceType<typeof Grid>>()
const breakPoint = computed<BreakPoint>(() => unref(gridRef)?.breakPoint || 'xl')

const searchForm = computed(() =>
  props.itemsProps.filter(item => {
    return !item.hidden
  })
)

const showCollapse = computed(() => {
  const { itemsProps, searchCols } = unref(getProps)
  let show = false
  itemsProps.reduce((prev, current) => {
    prev +=
      ((current.grid && current.grid[unref(breakPoint)]?.span) ?? current.grid?.span ?? 1) +
      ((current.grid && current.grid[unref(breakPoint)]?.offset) ?? current.grid?.offset ?? 0)

    if (typeof searchCols !== 'number') {
      if (prev >= searchCols[unref(breakPoint)]) show = true
    } else {
      if (prev >= searchCols) show = true
    }
    return prev
  }, 0)
  return show
})

const toggleCollapsed = (isCollapsed?: boolean) => {
  const { collapsed } = unref(getProps)
  if (isCollapsed === undefined) return setProps({ collapsed: !collapsed })
  return setProps({ collapsed: isCollapsed })
}
</script>
<style lang="scss" scoped></style>
